package com.yonyou.isv.demo.openapi.api;

import com.alibaba.fastjson.JSON;
import com.yonyou.isv.demo.openapi.base.module.auth.tenant.TenantAuthProvider;
import com.yonyou.isv.demo.openapi.base.properties.OpenApiProperties;
import com.yonyou.isv.demo.openapi.base.datacenter.DataCenterUrlProvider;
import com.yonyou.isv.demo.openapi.base.exception.BusinessException;
import com.yonyou.isv.demo.openapi.base.response.OpenApiResponse;
import com.yonyou.isv.demo.openapi.utils.RequestUtil;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 开放平台接口调用工具类
 * @author: nishch
 * @create: 2021-07-05
 **/
@Slf4j
@Component
public class BaseOpenApi{

    @Resource
    TenantAuthProvider tenantAuthProvider;
    @Resource
    @Getter
    RestTemplate restTemplate;
    @Resource
    @Getter
    OpenApiProperties properties;
    @Resource
    DataCenterUrlProvider  dataCenterUrlProvider;

    /**
     * 功能描述: get 请求
     * @Author: jiaoguojin
     * @Date: 2023/9/1 10:08
     */
    @SneakyThrows
    public <T> T getForEntity(String urlFragment, Map<String,String> params,Class<T> responseType) {
        String  reqUrl = buildGetRequestUrl(urlFragment,params);
        return RequestUtil.doGet(reqUrl,params,responseType);
    }

    /**
     * 功能描述: ContentType 为 application/json
     * @Author: jiaoguojin
     * @Date: 2023/9/1 9:49
     */
    @SneakyThrows
    public <T> T postForEntity(String urlFragment, Object params,Class<T> responseType) {
        if(params!=null)log.info("用友开放平台接口请求参数:"+ JSON.toJSON(params).toString());
        return RequestUtil.doPost(buildPostRequestUrl(urlFragment),params,responseType);
    }

    /**
     * 功能描述: ContentType 为 application/x-www-form-urlencoded
     * @Author: jiaoguojin
     * @Date: 2023/9/1 9:49
     */
    @SneakyThrows
    public <T> T postForEntityByForm(String urlFragment, Map<String, Object> params,Class<T> responseType) {
        if(params!=null)log.info("用友开放平台接口请求参数:"+ JSON.toJSON(params).toString());
        return RequestUtil.doPostByForm(buildPostRequestUrl(urlFragment),params,responseType);
    }

    /**
     * 请求体包含文件参数和业务参数  ContentType 为 multipart/form-data
     * @author jiaogjin
     * @date 2022/4/26 16:53
     * @return null
     */
    @SneakyThrows
    public <T> T fileForPost(String urlFragment,Map<String, Object> paramsMap,Class<T> responseType){
        return RequestUtil.doPostByFile(buildPostRequestUrl(urlFragment),paramsMap,responseType);
    }


    public <T> T getData(OpenApiResponse<T> body){
        if (body == null) {
            throw new BusinessException("unexpected response null when request open api isv access token");
        }
        body.check();
        log.info(JSON.toJSONString(body));
        return body.getData();
    }

    /**
     * 功能描述: 生成post请求地址
     * @Author: jiaoguojin
     * @Date: 2023/3/20 11:39
     */
    protected String buildPostRequestUrl(String urlFragment) {
        String host = dataCenterUrlProvider.buildBusinessUrl();
        Map<String,String> params = new HashMap<String, String>();
        params.put("access_token", tenantAuthProvider.buildTenantAuthToken().getAccessToken());
        String url = properties.concatParam(host+urlFragment,  properties.buildQueryString(params, false));
        log.info("用友开放平台接口请求:"+url);
        return url;
    }

    /**
     * 功能描述: 生成get请求地址
     * @Author: jiaoguojin
     * @Date: 2023/3/20 11:39
     */
    protected String buildGetRequestUrl(String urlFragment,Map<String,String> params){
        if(MapUtils.isEmpty(params)){
            return buildPostRequestUrl(urlFragment);
        }
        return properties.concatURL(buildPostRequestUrl(urlFragment), "&", properties.buildQueryString(params, false));
    }



}
